#include "DetectMe/Report.h"
#include <fstream>
#include <iostream>
#include "json/json.h"

using namespace std;

// void Report::addToReport(int DetectType, string fileName, int Line) {
//   Defects.push_back(defect(DetectType, fileName, Line));
// }

void Report::addToReport(DefectType dt, std::string fileName, int line) {
  if (defectsInfo.find(dt) != defectsInfo.end()) {
    if (defectsInfo[dt].find(fileName) != defectsInfo[dt].end()) {
      defectsInfo[dt][fileName].insert(line);
    } else {
      set<int> lines;
      lines.insert(line);
      defectsInfo[dt][fileName] = lines;
    }
  } else {
    set<int> lines;
    lines.insert(line);
    map<std::string, set<int>> files;
    files[fileName] = lines;
    defectsInfo[dt] = files;
  }
}

// void Report::writeJson() {
//   vector<defect> Defects = getDefects();
//   Json::Value root;
//   root["TotalDefects"] = (int)Defects.size();

//   for (auto it = Defects.begin(); it != Defects.end(); it++) {
//     Json::Value DefectNode;
//     DefectNode["DefectType"] = it->DefectType;
//     DefectNode["FileName"] = it->FileName;
//     DefectNode["Line"] = it->line;
//     root["Defects"].append(DefectNode);
//   }

//   Json::StyledWriter sw;
//   ofstream os;
//   os.open("Report.json");
//   os << sw.write(root);
//   os.close();
// }

void Report::writeJsonToFile() {
  int defectNum = 0;
  Json::Value root;
  for (std::map<DefectType, std::map<string, std::set<int>>>::iterator it1 =
           defectsInfo.begin();
       it1 != defectsInfo.end(); ++it1) {
    for (std::map<string, std::set<int>>::iterator it2 = it1->second.begin();
         it2 != it1->second.end(); ++it2) {
      for (std::set<int>::iterator it3 = it2->second.begin();
           it3 != it2->second.end(); ++it3) {
        Json::Value DefectNode;
        DefectNode["DefectType"] = int(it1->first);
        DefectNode["FileName"] = it2->first;
        DefectNode["Line"] = *it3;
        root["Defects"].append(DefectNode);
        defectNum++;
      }
    }
  }
  root["TotalDefects"] = defectNum;
  Json::StyledWriter sw;
  ofstream os;
  os.open("Report.json");
  os << sw.write(root);
  os.close();
  /*Json::StreamWriterBuilder builder;
  std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
  writer->write(root,&std::cout);*/
  
}
